package com.snowflake.ecatalog.service.profile;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;
import org.springside.modules.persistence.SearchFilter.Operator;

import com.snowflake.ecatalog.contant.ResourceInfoType;
import com.snowflake.ecatalog.contant.Status;
import com.snowflake.ecatalog.entity.Goods;
import com.snowflake.ecatalog.entity.ResourceInfo;
import com.snowflake.ecatalog.repository.GoodsDao;
import com.snowflake.ecatalog.util.LoginUtil;

//Spring Bean的标识.
@Service
// 默认将类中的所有public函数纳入事务管理.
@Transactional(readOnly = true)
public class GoodsService {
	@Autowired
	private GoodsDao goodsDao;
	@Autowired
	private ResouceInfoService resouceInfoService;
	private static final int RESOURCEINFO_TYPE = ResourceInfoType.GOODS;

	public Goods getGoods(Long id) {
		return goodsDao.findOne(id);
	}

	@Transactional(readOnly = false)
	public void saveGoods(Goods newGoods, List<ResourceInfo> resourceInfoList) {
		newGoods.setCreator(LoginUtil.getCurrentUser());
		newGoods.setCreatedTime(new Date());
		newGoods.setStatus(Status.DISABLE);
		Goods savedGoods = goodsDao.save(newGoods);
		for (ResourceInfo resourceInfo : resourceInfoList) {
			resourceInfo.setOwnerId(savedGoods.getId());
			resourceInfo.setOwnerType(RESOURCEINFO_TYPE);
		}
		resouceInfoService.saveResourceInfo(resourceInfoList);
	}

	@Transactional(readOnly = false)
	public void updateGoods(Goods goods, List<ResourceInfo> resourceInfoList) {
		goods.setLastModifier(LoginUtil.getCurrentUser());
		goods.setLastModifiedTime(new Date());
		Goods savedGoods = goodsDao.save(goods);
		// 更新ResourceInfo，保存新资源，删除无效资源
		resouceInfoService.updateResourceInfo(savedGoods.getId(), RESOURCEINFO_TYPE, resourceInfoList);
	}

	@Transactional(readOnly = false)
	public void deleteGoods(Long goodsId) {
		resouceInfoService.deleteResourceInfoFile(goodsId, RESOURCEINFO_TYPE);
		goodsDao.delete(goodsId);
	}

	public List<Goods> getAllGoods() {
		return (List<Goods>) goodsDao.findAll();
	}

	public Map<Integer, ResourceInfo> getImgPathMap(Long goodsId) {
		return resouceInfoService.getImgPathMap(goodsId, RESOURCEINFO_TYPE);
	}

	@Transactional(readOnly = false)
	public void enableGoods(Long id) {
		goodsDao.changeStatus(Status.ENABLE, id);
	}

	public boolean checkEnableGoods(Long id) {
		final int limit = 3; // 产品信息：三张图
		boolean result = true;
		List<ResourceInfo> resourceInfos = resouceInfoService.findByOwnerIdAndOwnerType(id, ResourceInfoType.GOODS);
		if (CollectionUtils.isEmpty(resourceInfos) || resourceInfos.size() < limit) {
			result = false;
		}
		return result;
	}

	@Transactional(readOnly = false)
	public void disableGoods(Long id) {
		goodsDao.changeStatus(Status.DISABLE, id);
	}

	public Page<Goods> getGoods(Long profileId, Map<String, Object> filterParams, int pageNumber, int pageSize) {
		PageRequest pageRequest = buildPageRequest(pageNumber, pageSize);
		Specification<Goods> spec = buildSpecification(profileId, filterParams);
		return goodsDao.findAll(spec, pageRequest);
	}

	/**
	 * 创建分页请求.
	 */
	private PageRequest buildPageRequest(int pageNumber, int pagzSize) {
		return new PageRequest(pageNumber - 1, pagzSize);
	}

	/**
	 * 创建动态查询条件组合.
	 */
	private Specification<Goods> buildSpecification(Long profileId, Map<String, Object> filterParams) {
		Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
		filters.put("category.profile.id", new SearchFilter("category.profile.id", Operator.EQ, profileId));
		Specification<Goods> spec = DynamicSpecifications.bySearchFilter(filters.values(), Goods.class);
		return spec;
	}
}
